| ======================================== | by Matthew Mecham | (c) 2001 - 2009 Invision Power Services | | ======================================== | | Time: <{%dyn.down.var.time%}> | Release: <{%dyn.down.var.md5%}> | | +--------------------------------------------------------------------------- | | > SSI script | > Script written by Matt Mecham | > Date started: 29th April 2002 | > UPDATED for 2.0: 1st July 2004 | > UPDATED for 2.1: 13th Sept 2005 | > UPDATED for 3.0: 26th Feb 2009 | +-------------------------------------------------------------------------- +-------------------------------------------------------------------------- | USAGE: +-------------------------------------------------------------------------- Simply call this script via PHP includes, or SSI .shtml tags to generate content on the fly, streamed into your own webpage. +-------------------------------------------------------------------------- | To show the board statistics +-------------------------------------------------------------------------- include("http://domain.com/forums/ssi.php?a=stats");/*noLibHook*//*TERANOTE: remove additional /* +-------------------------------------------------------------------------- | To show the active users stats (x Members, X Guests, etc) +-------------------------------------------------------------------------- include("http://domain.com/forums/ssi.php?a=active");/*noLibHook*//*TERANOTE: remove additional /* +-------------------------------------------------------------------------- | RSS / XML Syndication.. +-------------------------------------------------------------------------- RSS: http://domain.com/forums/ssi.php?a=out&f=1,2,3,4,5&show=10&type=rss XML: http://domain.com/forums/ssi.php?a=out&f=1,2,3,4,5&show=10&type=xml Will show last 10 topics in reverse chronological last post date order from all the forums in the comma separated list */ /** * Main executable wrapper. * * Set-up and load module to run * * @package IP.Board * @author Matt Mecham * @version 3.0 */ define( 'CCS_GATEWAY_CALLED', TRUE ); // Prevents redirect checks in ipsRegistry define( 'IPS_ENFORCE_ACCESS', TRUE ); // Prevents force login setting from returning a login page define( 'IPB_THIS_SCRIPT', 'public' ); require_once( './initdata.php' );/*noLibHook*/ require_once( IPS_ROOT_PATH . 'sources/base/ipsRegistry.php' );/*noLibHook*/ require_once( IPS_ROOT_PATH . 'sources/base/ipsController.php' );/*noLibHook*/ /** * Path to SSI templates directory * */ define( 'SSI_TEMPLATES_DIR', DOC_IPS_ROOT_PATH."ssi_templates" ); /** * Maximum number of topics to show * */ define( 'SSI_MAX_SHOW' , 100 ); /** * Allow SSI export. Enter "0" to turn off. * */ define( 'SSI_ALLOW_SYND' , 1 ); /* Go... */ $reg = ipsRegistry::instance(); $reg->init(); $ssi = new ssi( $reg ); class ssi { function __construct( ipsRegistry $registry ) { $this->registry = $registry; $this->DB = $this->registry->DB(); $this->settings =& $this->registry->fetchSettings(); $this->request =& $this->registry->fetchRequest(); $this->cache = $this->registry->cache(); $this->caches =& $this->registry->cache()->fetchCaches(); $this->member = $this->registry->member(); $this->memberData =& $this->registry->member()->fetchMemberData(); /* Load forums class */ $classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir('forums') . '/sources/classes/forums/class_forums.php', 'class_forums', 'forums' ); $this->registry->setClass( 'class_forums', new $classToLoad( $registry ) ); $this->registry->class_forums->forumsInit(); switch ($this->request['a']) { case 'active': $this->_doActive(); break; case 'stats': $this->_doStats(); break; case 'out': if ( SSI_ALLOW_SYND == 1 ) { $this->_doSyndication(); } else { exit(); } break; default: echo("An error occurred whilst processing this directive"); exit(); break; } } /** * Do Syndication * * Export topics / titles from selected forums * * @access protected */ protected function _doSyndication() { //---------------------------------------- // Sort out the forum ids //---------------------------------------- $tmp_forums = array(); $forums = array(); if ( $this->request['f'] ) { $tmp_forums = explode( ",", $this->request['f'] ); } else { fatal_error("Fatal error: no forum id specified"); } //---------------------------------------- // Intval the IDs //---------------------------------------- foreach ($tmp_forums as $f ) { $f = intval($f); if ( $f ) { $forums[] = $f; } } //---------------------------------------- // Check... //---------------------------------------- if ( count($forums) < 1 ) { fatal_error("Fatal error: no forum id specified"); } $sql_fields = implode( ",", $forums ); //---------------------------------------- // Number of topics to return? //---------------------------------------- $perpage = intval($this->request['show']) ? intval($this->request['show']) : 10; $perpage = ( $perpage > SSI_MAX_SHOW ) ? SSI_MAX_SHOW : $perpage; //---------------------------------------- // Load the template... //---------------------------------------- if ( $this->request['type'] == 'xml' ) { $template = $this->_loadTemplate("syndicate_xml.html"); } else { $template = $this->_loadTemplate("syndicate_rss.html"); } //---------------------------------------- // parse.. //---------------------------------------- $to_echo = ""; $top = ""; $row = ""; $bottom = ""; preg_match( "#\[TOP\](.+?)\[/TOP\]#is", $template, $match ); $top = trim($match[1]); preg_match( "#\[ROW\](.+?)\[/ROW\]#is", $template, $match ); $row = trim($match[1]); preg_match( "#\[BOTTOM\](.+?)\[/BOTTOM\]#is", $template, $match ); $bottom = trim($match[1]); //---------------------------------------- // Header parse... //---------------------------------------- //@header("Content-Type: text/xml;charset={$this->settings['gb_char_set']}"); //@header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); //@header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); //@header('Pragma: public'); $to_echo .= $this->_parseTemplate( $top, array ( 'board_url' => $this->settings['base_url'] , 'board_name' => $this->settings['board_name'] ) ); //---------------------------------------- // Fix up //---------------------------------------- $group = $this->caches['group_cache'][ $this->settings['guest_group'] ]; //---------------------------------------- // Get the topics, member info and other stuff //---------------------------------------- $this->DB->build( array( 'select' => '*', 'from' => 'topics', 'where' => "forum_id IN ($sql_fields) AND " . $this->registry->getClass('class_forums')->fetchTopicHiddenQuery( array( 'visible' ), '' ), 'order' => 'last_post DESC', 'limit' => array( 0, $perpage ) ) ); $this->DB->execute(); if ( ! $this->DB->getTotalRows() ) { fatal_error("Could not get the information from the database"); } while ( $i = $this->DB->fetch() ) { $forum = $this->registry->class_forums->forum_by_id[ $i['forum_id'] ]; if ( $this->registry->permissions->check( 'read', $forum ) != TRUE ) { continue; } if ( $forum['password'] != "" ) { continue; } $to_echo .= $this->_parseTemplate( $row, array ( 'topic_title' => str_replace( '&#', '&#', $i['title'] ), 'topic_id' => $i['tid'], 'topic_link' => $this->settings['base_url']."showtopic=".$i['tid'], 'forum_title' => htmlspecialchars($forum['name']), 'forum_id' => $i['forum_id'], 'last_poster_id' => $i['last_poster_id'], 'last_post_name' => $i['last_poster_name'], 'last_post_time' => $this->registry->getClass('class_localization')->getDate( $i['last_post'] , 'LONG', 1 ), 'timestamp' => $i['last_post'], 'starter_id' => $i['starter_id'], 'starter_name' => $i['starter_name'], 'board_url' => $this->settings['board_url'] , 'board_name' => $this->settings['board_name'], 'rfc_date' => date( 'r', $i['last_post'] ) ) ) . "\r\n"; } //---------------------------------------- // Print bottom... //---------------------------------------- echo $to_echo."\r\n".$bottom; exit(); } /** * Do Stats * * Show totals */ function _doStats() { //---------------------------------------- // Load the template... //---------------------------------------- $template = $this->_loadTemplate("stats.html"); //---------------------------------------- // INIT //---------------------------------------- $to_echo = ""; $time = time() - 900; $stats = $this->caches['stats']; $total_posts = $stats['total_replies'] + $stats['total_topics']; $to_echo = $this->_parseTemplate( $template, array( 'total_posts' => $total_posts, 'topics' => $stats['total_topics'], 'replies' => $stats['total_replies'], 'members' => $stats['mem_count'] ) ); echo $to_echo; exit(); } /** * Do Active * * Show active users */ function _doActive() { //-------------------------------- // Load the template... //-------------------------------- $template = $this->_loadTemplate("active.html"); //-------------------------------- // INIT //-------------------------------- $to_echo = ""; //-------------------------------- // Make sure we have a cut off... //-------------------------------- if ($this->settings['au_cutoff'] == "") { $this->settings['au_cutoff'] = 15; } //----------------------------------------- // Get the users from the DB //----------------------------------------- $cut_off = $this->settings['au_cutoff'] * 60; $time = time() - $cut_off; $rows = array(); $ar_time = time(); if ( $this->memberData['member_id'] ) { $rows = array( $ar_time => array( 'login_type' => IPSMember::isLoggedInAnon( $this->memberData ), 'running_time' => $ar_time, 'member_id' => $this->memberData['member_id'], 'member_name' => $this->memberData['members_display_name'], 'member_group' => $this->memberData['member_group_id'] ) ); } $this->DB->build( array( 'select' => 'id, member_id, member_name, login_type, running_time, member_group', 'from' => 'sessions', 'where' => "running_time > $time", ) ); $this->DB->execute(); //----------------------------------------- // FETCH... //----------------------------------------- while ( $r = $this->DB->fetch() ) { $rows[ $r['running_time'].'.'.$r['id'] ] = $r; } krsort( $rows ); //-------------------------------- // cache all printed members so we // don't double print them //-------------------------------- $cached = array(); $active = array(); foreach( $rows as $result ) { //----------------------------------------- // Bot? //----------------------------------------- if ( strstr( $result['id'], '_session' ) ) { //----------------------------------------- // Seen bot of this type yet? //----------------------------------------- $botname = preg_replace( '/^(.+?)=/', "\\1", $result['id'] ); if ( ! $cached[ $result['member_name'] ] ) { $cached[ $result['member_name'] ] = 1; } else { //----------------------------------------- // Yup, count others as guest //----------------------------------------- $active['GUESTS']++; } } //----------------------------------------- // Guest? //----------------------------------------- else if ( ! $result['member_id'] ) { $active['GUESTS']++; } //----------------------------------------- // Member? //----------------------------------------- else { if ( empty( $cached[ $result['member_id'] ] ) ) { $cached[ $result['member_id'] ] = 1; /* Reset login type in case the board/group setting got changed */ $result['login_type'] = IPSMember::isLoggedInAnon( array( 'login_anonymous' => $result['login_type'] ), $result['member_group'] ); if ( $result['login_type'] ) { $active['ANON']++; } else { $active['MEMBERS']++; } } } } $active['TOTAL'] = $active['MEMBERS'] + $active['GUESTS'] + $active['ANON']; $to_echo = $this->_parseTemplate( $template, array ( 'total' => $active['TOTAL'] ? $active['TOTAL'] : 0 , 'members' => $active['MEMBERS'] ? $active['MEMBERS'] : 0, 'guests' => $active['GUESTS'] ? $active['GUESTS'] : 0, 'anon' => $active['ANON'] ? $active['ANON'] : 0 ) ); echo $to_echo; exit(); } /** * Parse template * * Parses the template. Duh. * * @access protected * @param string Template data * @param array Array of data */ protected function _parseTemplate( $template, $assigned=array() ) { foreach( $assigned as $word => $replace) { $template = preg_replace( "/\{$word\}/i", "$replace", $template ); } $template = str_replace( '/ssi.php', '/index.php', $template ); return $this->registry->output->replaceMacros( $template ); } /** * Load template * * Loads the template * * @access protected * @param string Template to load */ protected function _loadTemplate($template="") { $filename = SSI_TEMPLATES_DIR."/".$template; if ( is_file($filename) ) { if ( $FH = fopen($filename, 'r') ) { $template = fread( $FH, filesize($filename) ); fclose($FH); } else { fatal_error("Couldn't open the template file"); } } else { fatal_error("Template file does not exist"); } return $template; } } function fatal_error( $error ) { print $error; exit(); }